<template>
  <div class="user-select-modal">
    <span class="input-group">
      <span class="input-data">
        <span class="value-item" :key="item.id" v-for="item in selectOptions">
          <span role="img" aria-label="China">
            <e-avatar :avatar="item.avatar" :nickname="item.nickname"/>
          </span>
          <a-tag color="blue" style="margin-left: 10px">{{ item.deptName }}</a-tag>
          {{ item.nickname }}
        </span>
      </span>
      <span class="input-group-addon">
        <a-button @click="() => {this.modalVisible = true}">选择</a-button>
      </span>
    </span>

    <a-modal v-model="modalVisible" :width="900" title="选择用户" @ok="handleOk">
      <a-row>
        <a-col :lg="8">
          <div style="padding: 0 10px">
            <a-tooltip placement="top" :visible="searchTooltipVisible">
              <template #title>
                <span>请输入部门名称后搜索</span>
              </template>
              <a-input-search v-model="deptKeyword" placeholder="输入部门名称搜索" @search="selectDept"/>
            </a-tooltip>

            <div class="tree-wrapper">
              <a-alert v-if="noResults" :style="{marginTop: '5px', marginBottom: '5px'}" message="未查询到数据" banner/>
              <tree
                :load-data="onLoadData"
                :tree-data="treeData"
                :expanded-keys="expandedKeys"
                :selected-keys="selectedKeys"
                show-icon
                draggable
                show-line
                @select="onSelect"
                @expand="onExpand"
              >
                <a-icon v-for="item in iconArrays" :key="item" :slot="item" :type="item"/>
              </tree>
              <a-button size="small" v-if="search" @click="firstLoadData">
                返回
              </a-button>
            </div>
          </div>
        </a-col>

        <a-col :lg="16">
          <div style="padding: 0 10px">
            <a-tooltip placement="top" :visible="searchUserTooltipVisible">
              <template #title>
                <span>请输入昵称或用户名后搜索</span>
              </template>
              <a-input-search style="margin-bottom: 10px" v-model="userKeyword" placeholder="请输入昵称或用户名搜索" @search="selectUser"/>
            </a-tooltip>

            <s-table
              ref="eTable"
              :columns="columns"
              :data="loadTableData"
              :alert="true"
              :rowSelection="rowSelection"
              showPagination="auto"
            >
              <template #sex="text, record">
                <e-dict-tag type="sex" :code="text"/>
              </template>
              <template #avatar="text, record">
                <e-avatar :avatar="text" :nickname="record.nickname"/>
              </template>
            </s-table>
          </div>
        </a-col>
      </a-row>
    </a-modal>
  </div>
</template>
<script>
import { select, selectByKeyword, selectUsersByIds } from '@/api/sys/user'
import { Tree } from 'ant-design-vue'
import { convertTree, isNotBlank } from '@/utils/util'
import EAvatar from '@/components/Easy/data-display/Avatar'
import PropTypes from 'ant-design-vue/es/_util/vue-types'
import { selectByPId, selectByTitle } from '@/api/sys/dept'
import { convertTreeData, generatorNodeIcon, updateNodeLeaf } from '@/utils/ant-design/data-display/tree'
import { STable } from '@/components'
import EDictTag from '@/components/Easy/data-display/DictTag'

const baseId = '0'

const columns = [
  {
    title: '用户名',
    dataIndex: 'username',
    sorter: true,
    width: 120
  },
  {
    title: '昵称',
    dataIndex: 'nickname',
    sorter: true,
    width: 120
  },
  {
    title: '头像',
    dataIndex: 'avatar',
    width: 80,
    scopedSlots: { customRender: 'avatar' }
  },
  {
    title: '性别',
    dataIndex: 'sex',
    sorter: true,
    width: 80,
    scopedSlots: { customRender: 'sex' }
  }
]

export default {
  name: 'EUserSearchModal',
  components: { EDictTag, EAvatar, Tree, STable },
  props: {
    // 设置 Select 的模式为多选或标签 'default' | 'multiple' | 'tags'
    mode: PropTypes.string.def('default'),
    // 数据范围，可以选择哪些用户 'all' | 'currentDept'
    range: PropTypes.string.def('all'),
    disabled: PropTypes.bool.def(false),
    allowClear: PropTypes.bool.def(true),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array])
  },
  data () {
    return {
      VUE_APP_API_BASE_URL: process.env.VUE_APP_API_BASE_URL,

      modalVisible: false,

      deptKeyword: '',
      search: false,
      noResults: false,
      searchTooltipVisible: false,

      // 树相关
      treeData: [],
      expandedKeys: [],
      selectedKeys: [],
      iconArrays: [],

      // 用户相关
      searchUserTooltipVisible: false,
      userKeyword: '',

      queryParam: {
        deptId: null
      },
      columns: columns,
      selectedRowKeys: [],
      selectedRows: [],

      fetching: false,
      selectOptions: [],

      currentValue: null
    }
  },
  created () {
    this.setValue(this.value)
  },
  mounted () {
    this.firstLoadData()
  },
  watch: {
    value (newValue) {
      // 如果值不同重新设置
      let isEqual = false
      if (newValue && Array.isArray(newValue)) {
        isEqual = this.currentValue.length === newValue.length && this.currentValue.filter(t => !newValue.includes(t))
      } else {
        isEqual = this.currentValue === newValue
      }
      if (!isEqual) {
        this.setValue(newValue)
      }
    }
  },
  computed: {
    rowSelection () {
      return {
        selectedRowKeys: this.selectedRowKeys,
        onChange: this.onSelectChange
      }
    }
  },
  methods: {
    onSelectChange (selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedRows = selectedRows
    },
    firstLoadData () {
      this.query = ''
      this.search = false
      this.noResults = false
      this.searchTooltipVisible = false
      selectByPId(baseId).then(res => {
        this.treeData = convertTreeData(convertTree(res.data))
        if (this.treeData[0].id === baseId) {
          this.treeData[0].selectable = false
        }
        // 默认展开根节点
        this.expandedKeys.push(baseId)
        this.iconArrays = generatorNodeIcon(this.treeData, this.iconArrays)
      })
    },
    onExpand (expandedKeys) {
      this.expandedKeys = expandedKeys
    },
    /**
     * 异步加载节点数据
     *
     * @param treeNode
     * @return {Promise<unknown>}
     */
    onLoadData (treeNode) {
      return new Promise(resolve => {
        if (treeNode.dataRef.children) {
          resolve()
          return
        }

        this.loadData(treeNode.dataRef, () => {
          resolve()
        })
      })
    },
    loadData (treeNode, callback) {
      selectByPId(treeNode.id).then(res => {
        treeNode.children = convertTreeData(res.data)
        updateNodeLeaf(treeNode)
        this.treeData = [...this.treeData]
        if (callback) {
          callback()
        }
        this.iconArrays = generatorNodeIcon(this.treeData, this.iconArrays)
      })
    },
    /**
     * 节点点击回调
     *
     * @param selectedKeys
     * @param e
     */
    onSelect (selectedKeys, e) {
      this.selectedKeys = selectedKeys
      if (e.node.dataRef.id !== baseId) {
        this.queryParam.deptId = e.node.dataRef.id
        this.$refs.eTable.refresh(true)
      }
    },
    selectDept () {
      if (isNotBlank(this.deptKeyword)) {
        this.searchTooltipVisible = false
        this.search = true
        selectByTitle(this.deptKeyword).then(res => {
          this.noResults = res.data.length === 0
          this.treeData = convertTreeData(res.data)
          this.iconArrays = generatorNodeIcon(this.treeData, this.iconArrays)
        })
      } else {
        this.searchTooltipVisible = true
      }
    },
    // 加载数据方法 必须为 Promise 对象
    loadTableData (parameter) {
      const requestParameters = Object.assign({}, parameter, this.queryParam)
      return select(requestParameters).then(res => {
          return res.data
        })
    },
    /**
     * 设置选中项
     *
     * @param value 选中项
     */
    setValue (value) {
      this.currentValue = value
      if (this.mode === 'multiple' && typeof value === 'undefined') {
        // 如果是多选，value必须为数组
        this.currentValue = []
      }
      if (this.currentValue == null || this.currentValue === '' || this.currentValue.length === 0) {
        this.selectOptions = []
        return
      }
      this.fetching = true
      const ids = value && Array.isArray(value) ? value.join(',') : value
      selectUsersByIds(ids).then(res => {
        this.selectOptions = res.data
        this.fetching = false
      })
    },
    /**
     * 查询用户
     *
     * @param value 关键字
     */
    selectUser () {
      if (isNotBlank(this.deptKeyword)) {
        this.searchTooltipVisible = false
        selectByKeyword(this.deptKeyword, this.range).then(res => {
          this.selectOptions = res.data.data
        })
      }
    },
    handleOk () {
      this.setValue(this.selectedRowKeys)
      this.modalVisible = false
    },
    /**
     * change 事件
     *
     * @param value
     */
    handleChange (value) {
      this.currentValue = value
      this.$emit('input', value)
      this.$emit('change')
    }
  }
}
</script>
<style lang="less">
.user-select-modal {
  .input-group {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
    position: relative;
    display: table;
    width: 100%;

    .input-data, .input-group-addon {
      display: table-cell;
      white-space: nowrap;
      vertical-align: middle;
    }

    .input-data {
      float: left;
      width: 100%;
      margin-bottom: 0;
      text-align: inherit;
      text-overflow: ellipsis;
      padding-left: 11px;
      border: 1px solid #d9d9d9;
      border-right: 0;
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px;

      .value-item {
        border: 1px solid #e8e8e8;
      }
    }

    .input-group-addon {
      position: relative;
      width: 1px;

      .ant-btn {
        height: 42px;
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
      }
    }
  }
}
</style>
